using System.Collections.Concurrent;
using Microsoft.AspNetCore.Http;
using UniversalAdminSystem.Application.FileStorage.DTOs;
using UniversalAdminSystem.Application.FileStorage.Interfaces;

namespace UniversalAdminSystem.Infrastructure.FileStorage;

public class LocalFileStorageService : IFileStorageService
{
    private readonly string _basePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads");
    private static readonly ConcurrentDictionary<string, FileDto> _fileIndex = new();

    public LocalFileStorageService()
    {
        if (!Directory.Exists(_basePath)) Directory.CreateDirectory(_basePath);
    }

    public async Task<FileInfo> SaveAsync(IFormFile file)
    {
        try
        {
            var uniqueFileName = Guid.NewGuid().ToString() + "_" + file.FileName;
            var filePath = Path.Combine(_basePath, uniqueFileName);
            using var stream = new FileStream(filePath, FileMode.Create);
            await file.CopyToAsync(stream);
            return new FileInfo(filePath);
        }
        catch
        {
            throw;
        }
    }

    public async Task<Stream> DownloadAsync(string fileName)
    {
        var filePath = Path.Combine(_basePath, fileName);

        if (!File.Exists(filePath)) throw new FileNotFoundException();
        var ms = new MemoryStream();
        using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            await fs.CopyToAsync(ms);
        }
        ms.Position = 0;
        return ms;
    }

    public Task DeleteAsync(string fileName)
    {
        var filePath = Path.Combine(_basePath, fileName);
        if (File.Exists(filePath)) File.Delete(filePath);
        _fileIndex.TryRemove(fileName, out _);
        return Task.CompletedTask;
    }

    public Task<IEnumerable<FileDto>> ListFilesAsync()
    {
        return Task.FromResult(_fileIndex.Values.AsEnumerable());
    }
}